﻿#include "mainwindow.h"
#include "ui_mainwindow.h"


#include <QImage>
#include <QLabel>
#include <QDebug>
#include <QPixmap>
#include <QHBoxLayout>


QImage Mat2QImage(cv::Mat const& src) {
    cv::Mat temp; // make the same cv::Mat
    cvtColor(src, temp,cv::COLOR_BGR2RGB); // cvtColor Makes a copt, that what i need
    QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
    dest.bits(); // enforce deep copy, see documentation
    return dest;
}

cv::Mat perspectiveTransform(cv::Mat const& src, std::vector<cv::Point2f> pts_dst) {
    // 原始图像的四个顶点坐标
    std::vector<cv::Point2f> pts_src;
    pts_src.push_back(cv::Point2f(0, 0));
    pts_src.push_back(cv::Point2f(src.cols - 1, 0));
    pts_src.push_back(cv::Point2f(src.cols - 1, src.rows - 1));
    pts_src.push_back(cv::Point2f(0, src.rows - 1));

    qDebug() << "Vector of points:";
    for (const auto& point : pts_src) {
        qDebug() << "(" << point.x << ", " << point.y << ")";
    }





    // 变换后的图像的四个顶点坐标


    qDebug() << "改变后 of points:";
    for (const auto& point : pts_dst) {
        qDebug() << "(" << point.x << ", " << point.y << ")";
    }

    // 计算透视变换矩阵
    cv::Mat perspective_matrix = cv::getPerspectiveTransform(pts_src, pts_dst);
    // 执行透视变换
    cv::Mat warped_image;
    cv::warpPerspective(src, warped_image, perspective_matrix, src.size());
    return warped_image;
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    cv::Mat input_image = cv::imread("i:/a.jpg");
    QPixmap pixmap("i:/a.jpg");
    int width = input_image.cols;
    int height = input_image.rows;

    cv::Point2f topLeft(0, 0);
    cv::Point2f topRight(width - 1, 0);
    cv::Point2f bottomRight(width - 1, height - 1);
    cv::Point2f bottomLeft(0, height - 1);


    std::stringstream ss1;
    ss1 << topLeft.x << "," << topLeft.y;
    this->ui->lineEdit_1->setText(ss1.str().c_str());


    std::stringstream ss2;
    ss2 << topRight.x << "," << topRight.y;

    this->ui->lineEdit_2->setText(ss2.str().c_str());

    std::stringstream ss3;
    ss3 << bottomRight.x << "," << bottomRight.y;

    this->ui->lineEdit_3->setText(ss3.str().c_str());

    std::stringstream ss4;
    ss4 << bottomLeft.x << "," << bottomLeft.y;

    this->ui->lineEdit_4->setText(ss4.str().c_str());



    this->ui->label->setPixmap(pixmap);
    this->ui->label->setScaledContents(true);





}



MainWindow::~MainWindow()
{
    delete ui;
}

cv::Mat QImageToCvMat(const QImage &image) {
    cv::Mat mat;

    // 将 QImage 转换为 cv::Mat
    switch (image.format()) {
    case QImage::Format_RGB888:
        mat = cv::Mat(image.height(), image.width(), CV_8UC3, const_cast<uchar*>(image.bits()), image.bytesPerLine());
        cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR); // 转换通道顺序
        break;
    case QImage::Format_Indexed8:
        mat = cv::Mat(image.height(), image.width(), CV_8UC1, const_cast<uchar*>(image.bits()), image.bytesPerLine());
        break;
    default:
        QImage convertedImage = image.convertToFormat(QImage::Format_RGB888);
        mat = cv::Mat(convertedImage.height(), convertedImage.width(), CV_8UC3, const_cast<uchar*>(convertedImage.bits()), convertedImage.bytesPerLine());
        cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR); // 转换通道顺序
        break;
    }

    return mat;
}

void MainWindow::on_pushButton_clicked()
{

    QStringList list1  =this->ui->lineEdit_1->text().split(",");
    QStringList list2  =this->ui->lineEdit_2->text().split(",");
    QStringList list3  =this->ui->lineEdit_3->text().split(",");
    QStringList list4 =this->ui->lineEdit_4->text().split(",");


    std::vector<cv::Point2f> pts_dst;
    pts_dst.push_back(cv::Point2f(list1.at(0).toInt(), list1.at(1).toInt()));
    pts_dst.push_back(cv::Point2f(list2.at(0).toInt(), list2.at(1).toInt()));
    pts_dst.push_back(cv::Point2f(list3.at(0).toInt(), list3.at(1).toInt()));
    pts_dst.push_back(cv::Point2f(list4.at(0).toInt(), list4.at(1).toInt()));

      cv::Mat input_image = cv::imread("i:/a.jpg");

    cv::Mat transformed_image = perspectiveTransform(input_image,pts_dst);

//            // 将OpenCV Mat转换为Qt QImage
    QImage transformed_qimage = Mat2QImage(transformed_image);
//                // 将QImage转换为QPixmap以便显示
     QPixmap pixmap = QPixmap::fromImage(transformed_qimage);

//        // 将图像设置到QLabel上显示
      this->ui->label->setPixmap(pixmap);
       this->ui->label->setScaledContents(true);
}
